﻿#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include "gtBMP.h"
#include "EagleDefine.h"
// #include "ChangGS.h"
// #include "ChengGS.h"
// #include "XiAnGS.h"
#include <Windows.h>

#define BMP_DBG 0
#if BMP_DBG
void bmpDbg(char * str)
{
    FILE *dbg_fp = fopen("bmp.dbg", "a");
    fprintf(dbg_fp, "%s\n", str);
    fclose(dbg_fp);
}
#else
void bmpDbg(char * str) {}
#endif
static const unsigned int grey8_palette[256] = {
    0x0, 0x10101, 0x20202, 0x30303, 0x40404, 0x50505, 0x60606, 0x70707,
    0x80808, 0x90909, 0xa0a0a, 0xb0b0b, 0xc0c0c, 0xd0d0d, 0xe0e0e, 0xf0f0f,
    0x101010, 0x111111, 0x121212, 0x131313, 0x141414, 0x151515, 0x161616, 0x171717,
    0x181818, 0x191919, 0x1a1a1a, 0x1b1b1b, 0x1c1c1c, 0x1d1d1d, 0x1e1e1e, 0x1f1f1f,
    0x202020, 0x212121, 0x222222, 0x232323, 0x242424, 0x252525, 0x262626, 0x272727,
    0x282828, 0x292929, 0x2a2a2a, 0x2b2b2b, 0x2c2c2c, 0x2d2d2d, 0x2e2e2e, 0x2f2f2f,
    0x303030, 0x313131, 0x323232, 0x333333, 0x343434, 0x353535, 0x363636, 0x373737,
    0x383838, 0x393939, 0x3a3a3a, 0x3b3b3b, 0x3c3c3c, 0x3d3d3d, 0x3e3e3e, 0x3f3f3f,
    0x404040, 0x414141, 0x424242, 0x434343, 0x444444, 0x454545, 0x464646, 0x474747,
    0x484848, 0x494949, 0x4a4a4a, 0x4b4b4b, 0x4c4c4c, 0x4d4d4d, 0x4e4e4e, 0x4f4f4f,
    0x505050, 0x515151, 0x525252, 0x535353, 0x545454, 0x555555, 0x565656, 0x575757,
    0x585858, 0x595959, 0x5a5a5a, 0x5b5b5b, 0x5c5c5c, 0x5d5d5d, 0x5e5e5e, 0x5f5f5f,
    0x606060, 0x616161, 0x626262, 0x636363, 0x646464, 0x656565, 0x666666, 0x676767,
    0x686868, 0x696969, 0x6a6a6a, 0x6b6b6b, 0x6c6c6c, 0x6d6d6d, 0x6e6e6e, 0x6f6f6f,
    0x707070, 0x717171, 0x727272, 0x737373, 0x747474, 0x757575, 0x767676, 0x777777,
    0x787878, 0x797979, 0x7a7a7a, 0x7b7b7b, 0x7c7c7c, 0x7d7d7d, 0x7e7e7e, 0x7f7f7f,
    0x808080, 0x818181, 0x828282, 0x838383, 0x848484, 0x858585, 0x868686, 0x878787,
    0x888888, 0x898989, 0x8a8a8a, 0x8b8b8b, 0x8c8c8c, 0x8d8d8d, 0x8e8e8e, 0x8f8f8f,
    0x909090, 0x919191, 0x929292, 0x939393, 0x949494, 0x959595, 0x969696, 0x979797,
    0x989898, 0x999999, 0x9a9a9a, 0x9b9b9b, 0x9c9c9c, 0x9d9d9d, 0x9e9e9e, 0x9f9f9f,
    0xa0a0a0, 0xa1a1a1, 0xa2a2a2, 0xa3a3a3, 0xa4a4a4, 0xa5a5a5, 0xa6a6a6, 0xa7a7a7,
    0xa8a8a8, 0xa9a9a9, 0xaaaaaa, 0xababab, 0xacacac, 0xadadad, 0xaeaeae, 0xafafaf,
    0xb0b0b0, 0xb1b1b1, 0xb2b2b2, 0xb3b3b3, 0xb4b4b4, 0xb5b5b5, 0xb6b6b6, 0xb7b7b7,
    0xb8b8b8, 0xb9b9b9, 0xbababa, 0xbbbbbb, 0xbcbcbc, 0xbdbdbd, 0xbebebe, 0xbfbfbf,
    0xc0c0c0, 0xc1c1c1, 0xc2c2c2, 0xc3c3c3, 0xc4c4c4, 0xc5c5c5, 0xc6c6c6, 0xc7c7c7,
    0xc8c8c8, 0xc9c9c9, 0xcacaca, 0xcbcbcb, 0xcccccc, 0xcdcdcd, 0xcecece, 0xcfcfcf,
    0xd0d0d0, 0xd1d1d1, 0xd2d2d2, 0xd3d3d3, 0xd4d4d4, 0xd5d5d5, 0xd6d6d6, 0xd7d7d7,
    0xd8d8d8, 0xd9d9d9, 0xdadada, 0xdbdbdb, 0xdcdcdc, 0xdddddd, 0xdedede, 0xdfdfdf,
    0xe0e0e0, 0xe1e1e1, 0xe2e2e2, 0xe3e3e3, 0xe4e4e4, 0xe5e5e5, 0xe6e6e6, 0xe7e7e7,
    0xe8e8e8, 0xe9e9e9, 0xeaeaea, 0xebebeb, 0xececec, 0xededed, 0xeeeeee, 0xefefef,
    0xf0f0f0, 0xf1f1f1, 0xf2f2f2, 0xf3f3f3, 0xf4f4f4, 0xf5f5f5, 0xf6f6f6, 0xf7f7f7,
    0xf8f8f8, 0xf9f9f9, 0xfafafa, 0xfbfbfb, 0xfcfcfc, 0xfdfdfd, 0xfefefe, 0xffffff
};


static unsigned char HexToBcd(unsigned short value)
{
    return (value / 0x10) * 10 + value % 0x10;
}

gtBMP::gtBMP(int _width, int _height, int _color_depth, unsigned char *_buffer, unsigned int _buf_size, bool up_down_reverse, bool left_right_reverse)
{
    int new_column;
    _color_depth = ((_color_depth + 7) / 8) * 8;
    int n = 32 / _color_depth;
    new_column = (_width + n - 1) / n; // 四字节对齐
    new_column = new_column * n;
    bmp.header.identifiler = 'MB';
    bmp.header.reversed1 = 0;
    bmp.header.reversed2 = 0;
    bmp.header.bitmap_header_size = 0x28U;
    bmp.header.width = (unsigned int)_width;
    bmp.header.height = (unsigned int)_height;
    bmp.header.planes = 1U;
    bmp.header.compression = 0x00;
    bmp.header.hResolution = 0/*0x31d4*/;
    bmp.header.vResolution = 0/*0x31d4*/;
    bmp.header.colors = 0U;
    bmp.header.important_colors = 0U;
    if (_color_depth == 8)
    {
        bmp.header.file_size = (unsigned int)(new_column * _height + sizeof(struct gtBmpHeader) + sizeof(grey8_palette) + sizeof(struct gtBmpExtension));
        bmp.header.bitmap_data_offset = (unsigned int)(sizeof(struct gtBmpHeader) + sizeof(grey8_palette) + sizeof(struct gtBmpExtension));
        bmp.header.bits_per_pixel = 8U;
        bmp.header.bitmap_data_size = (unsigned int)(new_column * _height);
        bmp.palette = (unsigned int*)grey8_palette;
        bmp.data = (unsigned char*)malloc(new_column * _height);
        if (bmp.data)
        {
            //for (int line = 0; line < _height; line++)
            //{
            //	memcpy(bmp.data + line * new_column, _buffer + _width * (_height - line - 1), _width);
            //}

            int pix_num = new_column * _height;
            if (up_down_reverse && left_right_reverse == false)
            {
                memcpy(bmp.data, _buffer, bmp.header.bitmap_data_size);
            }
            if (up_down_reverse == false && left_right_reverse)
            {
                for (int i = 0; i < pix_num; i++){
                    bmp.data[pix_num - i - 1] = _buffer[i];
                }
            }
            if (up_down_reverse && left_right_reverse)
            {
                for (int i = 0; i < _height; i++)
                {
                    for (int j = 0; j < new_column; j++)
                    {
                        bmp.data[new_column * i + j] = _buffer[new_column * i + (new_column - 1 - j)];
                    }
                }
            }
            if (up_down_reverse == false && left_right_reverse == false)
            {
                for (int line = 0; line < _height; line++)
                {
                    memcpy(bmp.data + line * new_column, _buffer + (_height - line - 1) * new_column, new_column);
                }
            }
            own_data = true;
        }
    }
    else if (_color_depth == 16)
    {
        int nOffset = sizeof(struct gtBmpHeader) + sizeof(struct gtBmpExtension);
#if defined(CHENGGS_VERSION) && (CHENGGS_VERSION == 3 || CHENGGS_VERSION == 4) // 三期不需要 写入扩展信息 否则bmp 本地无法预览
        nOffset = sizeof(struct gtBmpHeader);
#endif
        bmp.header.file_size = (unsigned int)(new_column * _height + nOffset);
        bmp.header.bitmap_data_offset = nOffset;
        bmp.header.bits_per_pixel = 16U;
        bmp.header.bitmap_data_size = (unsigned int)(new_column * _height * 2);
        bmp.palette = NULL;
        // #ifdef XIANGS_VERSION
        // 		bmp.palette = (unsigned int*)grey8_palette;
        // #endif
        bmp.data = (unsigned char*)malloc(new_column * _height * 2);
        if (bmp.data)
        {
            ///*扫描行是由底向上存储的，这就是说，阵列中的第一个字节表示位图左下角的像素，而最后一个字节表示位图右上角的像素*/
            /*for (int line = 0; line < _height; line++)
            {
            memcpy(bmp.data + line * new_column * 2, _buffer + _width * (_height - line - 1) * 2, _width * 2);
            }*/

            unsigned short* dest_buf = (unsigned short*)bmp.data;
            unsigned short* orgi_buf = (unsigned short*)_buffer;
            int pix_num = new_column * _height;
            if (up_down_reverse && left_right_reverse == false)
            {
                memcpy(bmp.data, _buffer, bmp.header.bitmap_data_size);
            }
            if (up_down_reverse == false && left_right_reverse)
            {
                for (int i = 0; i < pix_num; i++){
                    dest_buf[pix_num - i - 1] = orgi_buf[i];
                }
            }
            if (up_down_reverse && left_right_reverse)
            {
                for (int i = 0; i < _height; i++)
                {
                    for (int j = 0; j < new_column; j++)
                    {
                        dest_buf[new_column * i + j] = orgi_buf[new_column * i + (new_column - 1 - j)];
                    }
                }
            }
            if (up_down_reverse == false && left_right_reverse == false)
            {
                for (int line = 0; line < _height; line++)
                {
                    memcpy(bmp.data + line * new_column * 2, _buffer + (_height - line - 1) * new_column * 2, new_column * 2);
                }
            }
            own_data = true;
        }
    }
    else
    {
        ok = false;
        bmpDbg("not support bmp type");
    }

    ok = true;
    return;
}

gtBMP::gtBMP(int _width, int _height, unsigned char* buffer, unsigned int _buf_size)
{
    bmp.header.identifiler = 'MB';
    bmp.header.reversed1 = 0;
    bmp.header.reversed2 = 0;
    bmp.header.bitmap_header_size = 0x28U;
    bmp.header.width = (unsigned int)_width;
    bmp.header.height = (unsigned int)_height;
    bmp.header.planes = 1U;
    bmp.header.compression = 0x00;
    bmp.header.hResolution = 0x31d4;
    bmp.header.vResolution = 0x31d4;
    bmp.header.colors = 0U;
    bmp.header.important_colors = 0U;
    int nOffset = sizeof(struct gtBmpHeader) + sizeof(struct gtBmpExtension);
#if defined(CHENGGS_VERSION) && (CHENGGS_VERSION == 3|| CHENGGS_VERSION == 4) // 三期不需要 写入扩展信息 否则bmp 本地无法预览
    nOffset = sizeof(struct gtBmpHeader);
#endif
    bmp.header.file_size = (unsigned int)(_width * _height * 3 + nOffset);
    bmp.header.bitmap_data_offset = (unsigned int)(nOffset);
    bmp.header.bits_per_pixel = 24U;
    bmp.header.bitmap_data_size = (unsigned int)(_width * _height * 3);
    bmp.palette = NULL;
    bmp.data = (unsigned char*)malloc(_width * _height * 3);
    int pix_num = _width * _height;
    if (bmp.data)
    {

        //		if (up_down_reverse && left_right_reverse == false)
        //		{
        //			for (int line = 0; line < _height; line++)
        //			{
        //				for (int i = 0; i < _width; i++)
        //				{
        //					bmp.data[(_width * line + i) * 3 + 0] = buffer[(_width * (_height - line) - i - 1) * 3 + 2];
        //					bmp.data[(_width * line + i) * 3 + 1] = buffer[(_width * (_height - line) - i - 1) * 3 + 1];
        //					bmp.data[(_width * line + i) * 3 + 2] = buffer[(_width * (_height - line) - i - 1) * 3 + 0];
        //				}
        //			}
        //		}
        //		if (up_down_reverse == false && left_right_reverse)
        //		{		
        //			for (int line = 0; line < _height; line++)
        //			{
        //				for (int i = 0; i < _width; i++)
        //				{
        //					bmp.data[(_width * line + i) * 3 + 0] = buffer[(_width * line + i) * 3 + 2];
        //					bmp.data[(_width * line + i) * 3 + 1] = buffer[(_width * line + i) * 3 + 1];
        //					bmp.data[(_width * line + i) * 3 + 2] = buffer[(_width * line + i) * 3 + 0];
        //				}
        //			}
        ////			memcpy(bmp.data, buffer, bmp.header.bitmap_data_size);
        //		}
        //		if (up_down_reverse && left_right_reverse)
        //		{
        //			for (int line = 0; line < _height; line++)
        //			{
        //				for (int i = 0; i < _width; i++)
        //				{
        //					bmp.data[(_width * line + i) * 3 + 0] = buffer[(_width * (_height - line - 1) + i) * 3 + 2];
        //					bmp.data[(_width * line + i) * 3 + 1] = buffer[(_width * (_height - line - 1) + i) * 3 + 1];
        //					bmp.data[(_width * line + i) * 3 + 2] = buffer[(_width * (_height - line - 1) + i) * 3 + 0];
        //				}
        //			}
        //		}
        //		if (up_down_reverse == false && left_right_reverse == false)
        //		{

        for (int line = 0; line < _height; line++)
        {
            for (int i = 0; i < _width; i++)
            {
                bmp.data[(_width * line + i) * 3 + 0] = buffer[(_width * (line + 1) - i - 1) * 3 + 2];
                bmp.data[(_width * line + i) * 3 + 1] = buffer[(_width * (line + 1) - i - 1) * 3 + 1];
                bmp.data[(_width * line + i) * 3 + 2] = buffer[(_width * (line + 1) - i - 1) * 3 + 0];
            }
        }

        own_data = true;
    }
    ok = true;
    return;
}

gtBMP::~gtBMP()
{
    if (own_data)
        free(bmp.data);
}

#if 0

void setExtraInfo(gtBmpExtension* extension, int _width, int _height, int _color_depth,
    int data_source, unsigned char *_buffer, unsigned int _buf_size, long vendor, gtBmpHeader* header)
{
    unsigned char* extension_data_source = 0;
    unsigned int data_size = 0;
    memset(extension, 0x00, sizeof(gtBmpExtension));
    _color_depth = ((_color_depth + 7) / 8) * 8;

    if (vendor == E_VENDOR_CHENGS)  //成光所格式
    {
        if (_color_depth == 8)
            return;

        if (data_source == 1)  // 光纤 通道
        {
            data_size = _width * (_color_depth / 8);
            extension_data_source = _buffer + (_height - 1) * _width * (_color_depth / 8);
        }
        else if (data_source == 2) // 2路光纤
        {
            extension_data_source = new unsigned char[_width / 2 * (_color_depth / 8)];
            data_size = _width / 2 * (_color_depth / 8);
#ifdef _DEBUG
            unsigned short* tmpBuf = (unsigned short*)_buffer + _width * (_height - 1);
#endif // DEBUG
            // 图像数据中嵌入的信息在每个相机光纤数据第一路中的图像数据最后一行

#if (defined(CHENGGS_VERSION)&&(CHENGGS_VERSION == 3 || CHENGGS_VERSION == 4)) 
            // 双字节 0 -- width/2 [12/21/2016 ejitec]
            if (_width == 1392 * 4)  // ctv
            {
                for (int i = 0; i < _width; i += 4) // 考虑 1392*4 * 1040
                {
                    *((unsigned short*)extension_data_source + i / 4) = *((unsigned short*)_buffer + _width * (_height - 1) + i);
                }
            }
            else    // mtv
            {
                for (int i = 0; i < _width; i += 2) //
                {
                    if (CHENGGS_VERSION == 4)
                    {
                        *((unsigned short*)extension_data_source + i / 2) = *((unsigned short*)_buffer + _width * (_height - 1) + i);
                    }
                    else
                    {
                        *((unsigned short*)extension_data_source + i / 2) = *((unsigned short*)_buffer + _width * (_height - 1) + i + 1);
                    }
                }
            }
#else  // 二期 和 五期 [4/24/2017 xystar]
            for (int i = 0; i < _width; i += 4)
            {
                // 双字节 0 -- width/2 [12/21/2016 ejitec]
                *((unsigned short*)extension_data_source + i / 2) = *((unsigned short*)_buffer + _width * (_height - 1) + i);
                *((unsigned short*)extension_data_source + i / 2 + 1) = *((unsigned short*)_buffer + _width * (_height - 1) + i + 1);
            }
#endif

        }
    }

    if (extension_data_source == 0)
        return;
    setExtraInfo(extension, extension_data_source, data_size, vendor, header);

    if (data_source == 2)
    {
        delete extension_data_source;
        extension_data_source = nullptr;
    }
}

// 解析对应 的 帧表示信息
void setExtraInfo(gtBmpExtension* extension, unsigned char* buffer, unsigned int buffer_size, long vendor, gtBmpHeader* header)
{
    memset(extension, 0x00, sizeof(gtBmpExtension));

    if (vendor == E_VENDOR_CHENGS) //成光所格式
    {
        int nVersion = 2;

#ifdef CHENGGS_VERSION
        nVersion = CHENGGS_VERSION;
#endif // CHENGGS_VERSION

#if (CHENGGS_VERSION == 3 || CHENGGS_VERSION == 4)  // 复用 变量 cgs_data
        CHENG_GS_DATA_Ver3* cgs_data = (CHENG_GS_DATA_Ver3*)buffer;
        if (cgs_data->frame_start != CHENGGS_FRAME_START /*|| (cgs_data->frame_end[0] & CHENGGS_FRAME_END) != 0x55aa*/)
            return;
#else
        CHENG_GS_DATA* cgs_data = (CHENG_GS_DATA*)buffer;
        if (cgs_data->frame_start != CHENGGS_FRAME_START || (cgs_data->frame_end & CHENGGS_FRAME_END) != CHENGGS_FRAME_END)
            return;
#endif
        // 用于实时显示 [12/22/2016 ejitec]
        extension->current_time = ((HexToBcd(cgs_data->hour) * 3600 + HexToBcd(cgs_data->minite) * 60 + HexToBcd(cgs_data->second)) * 1000 + cgs_data->milisecond) * 10;
        extension->distance = (cgs_data->target_distance[2] << 16 | (unsigned char)cgs_data->target_distance[1] << 8 | (unsigned char)cgs_data->target_distance[0]) * 100;
        unsigned long fraps = 25;

        if (nVersion == 2 || nVersion == 5)
        {
            switch (cgs_data->sync_fraps[0])
            {
            case 0:
                fraps = 25;
                break;
            case 1:
                fraps = 50;
                break;
            case 2:
                fraps = 100;
                break;
            case 3:
                fraps = 200;
                break;
            default:
                break;
            }


            extension->azimuth_angle = ((unsigned char)cgs_data->decoderA[2] << 16 | (unsigned char)cgs_data->decoderA[1] << 8 | (unsigned char)cgs_data->decoderA[0]) * (0x80000000 / 0x01000000);
            extension->pitch_angle = ((unsigned char)cgs_data->decoderE[2] << 16 | (unsigned char)cgs_data->decoderE[1] << 8 | (unsigned char)cgs_data->decoderE[0]) * (0x80000000 / 0x01000000);
            //		extension->device_status = cgs_data->device_type;
            //		extension->device_status = cgs_data->device_type;
            extension->focal_len = (cgs_data->focal_len[1] << 8 | cgs_data->focal_len[0]) * 100;
        }
        else if (nVersion == 3 || nVersion == 4)
        {
            switch (cgs_data->sync_fraps[0])
            {
            case 0:
                fraps = 25;
                break;
            case 1:
                fraps = 50;
                break;
            case 2:
                fraps = 100;
                break;
            case 3:
                fraps = 200;
                break;
            case 4:
                fraps = 500;
                break;
            case 5:
                fraps = 1000;
                break;
            default:
                break;
            }

            double height = (cgs_data->decoderA[2] << 16 | cgs_data->decoderA[1] << 8 | cgs_data->decoderA[0])*360.0 / 16777216;
            double direction = (cgs_data->decoderE[2] << 16 | cgs_data->decoderE[1] << 8 | cgs_data->decoderE[0])*360.0 / 16777216;
            if (direction > 355)
            {
                direction -= 360;
            }

            extension->azimuth_angle = (unsigned int)(height * 1000000);
            extension->pitch_angle = (unsigned int)((direction + 5) * 1000000);
            unsigned short focal = (cgs_data->focal_len[1] << 8 | cgs_data->focal_len[0]);
            extension->focal_len = focal * 100;

            if (header != NULL)
            {
                unsigned int Temms = cgs_data->milisecond / 10;
                unsigned char bcdTenMs = (Temms / 10) << 4 | (Temms % 10);
                header->reversed1 = (unsigned char)cgs_data->minite << 8 | (unsigned char)cgs_data->hour;
                header->reversed2 = bcdTenMs << 8 | (unsigned char)cgs_data->second;
                header->hResolution = extension->azimuth_angle;
                header->vResolution = extension->pitch_angle;
                header->important_colors = ((cgs_data->milisecond % 10) << 16) | (focal);
            }
        }
        extension->fraps = (fraps)* 100;
        extension->integration_time = ((unsigned char)cgs_data->exposure_time[2] << 16 | (unsigned char)cgs_data->exposure_time[1] << 8 | (unsigned char)cgs_data->exposure_time[0]) / 100;
        // 日期 和 设备编号
        unsigned long dwDate = cgs_data->date[3] << 24 | cgs_data->date[2] << 16 | cgs_data->date[1] << 8 | cgs_data->date[0];
        unsigned short devType = cgs_data->device_type[1] << 8 | cgs_data->device_type[0];
        memcpy(extension->reserved, &dwDate, sizeof(unsigned long));
        memcpy(extension->reserved + 4, &devType, sizeof(unsigned short));
    }
    else if (vendor == E_VENDOR_CHANGGS) // 长春光所格式
    {
        CHANG_GS_DATA* cgs_data = (CHANG_GS_DATA*)buffer;
        if ((cgs_data->frame_start != CHANGGS_FRAME_START)
            || (cgs_data->frame_end != CHANGGS_FRAME_END))
            return;

#if CHANGGS_VERSION == 2

        BmpExtensionInfo_ChangGSVer2* bmpExt = new BmpExtensionInfo_ChangGSVer2(cgs_data);
#else

        BaseBmpExtensionInfo* bmpExt = 0;
        switch (cgs_data->camera_type)
        {
        case CHANGGS_DEVICE_TYPE_TELEPHOTO:
            bmpExt = new TelePhotoBmpExtensionInfo(cgs_data);
            break;
        case CHANGGS_DEVICE_TYPE_LARGEFIELD:
            bmpExt = new largeFieldBmpExtensionInfo(cgs_data);
            break;
        case CHANGGS_DEVICE_TYPE_MEDIUMWAVE:
            bmpExt = new MediumWaveBmpExtensionInfo(cgs_data);
            break;
        case CHANGGS_DEVICE_TYPE_LONGWAVE:
            bmpExt = new LongWaveBmpExtensionInfo(cgs_data);
            break;
        default:
            break;
        }
#endif
        if (bmpExt == 0)
            return;
        memcpy(extension, bmpExt->GetBmpExtension(), sizeof(gtBmpExtension));
        delete bmpExt;
    }
    else if (vendor == E_VENDOR_XIANGS)  // 西安所 [12/12/2016 ejitec]
    {
        if (!buffer)
        {
            return;
        }

        XIAN_GS_DATA* xian_data = (XIAN_GS_DATA*)buffer;

#if (defined(XIANGS_VERSION) && XIANGS_VERSION == 1)

        unsigned long mutilHead = 0xAA55feff, mutilHeadRcv = 0;
        if (xian_data->m_tHead == XiAnHead())  // 头部校验
        {
            memcpy(&extension->current_time, xian_data->m_szUdpGps + 1, 4);
            extension->current_time *= 10;
            memcpy(&mutilHeadRcv, xian_data->m_szUdpMuti_1, 4);

            if (mutilHead == mutilHeadRcv)
            {
                float fTemp = .0;  // 避免强制转换 将 小数 负略
                memcpy(&fTemp, xian_data->m_szUdpMuti_1 + 12, 4);
                extension->azimuth_angle = fTemp * 0x80000000;
                memcpy(&fTemp, xian_data->m_szUdpMuti_1 + 16, 4);
                extension->pitch_angle = fTemp * 0x80000000;
            }
            // short [12/14/2016 ejitec]
            memcpy(&extension->focal_len, xian_data->m_szUdpSingle + 30, 2);
            extension->focal_len *= 10;
        }

#else
        /************************************************************************/
        /*

        方位角	A	4	二进制补码	360°/231
        俯仰角	E	4	二进制补码	360°/231
        焦距	f	4	无符号二进制整数	0.01mm
        距离值	R	8	无符号二进制整数	0.001m	固定填全“0”表示无距离值。
        帧频	F	4	无符号二进制整数	0.01帧/s

        */
        /************************************************************************/
        int nPos = 0;
        int nTmOffset = 0;
        memcpy(&nTmOffset, buffer + sizeof(XIAN_GS_DATA), 4);
        memcpy(&nPos, buffer + sizeof(XIAN_GS_DATA) + 4, 4);
        memcpy(&extension->current_time, xian_data->m_szUdp1_tm, 4);
        extension->current_time += nTmOffset;
        extension->current_time *= 10;
        float fTemp = 0.0;  // 避免强制转换 将 小数 负略
        memcpy(&fTemp, xian_data->m_szUdp2_Aangle + 4 * nPos, 4);
        extension->azimuth_angle = (double)fTemp / 360 * 0x80000000;
        memcpy(&fTemp, xian_data->m_szUdp2_Eangle + 4 * nPos, 4);
        extension->pitch_angle = (double)fTemp / 360 * 0x80000000;
        memcpy(&extension->focal_len, xian_data->m_szUdp3_focal, 4);  // 0.01mm
        memcpy(&extension->distance, xian_data->m_szUdp3_distance, 4);
        memcpy(&extension->fraps, xian_data->m_szUdp3_fraps, 4);
        memcpy(&extension->integration_time, xian_data->m_szUdp3_exposureTm, 4);
        memcpy(&extension->device_status, xian_data->m_szUdp3_status, 1);  // 设备状态取第一个

#endif
    }
}

#endif

void gtBMP::writeToFile(std::wstring file_name)
{
    if (ok == false)
        return;

#ifdef CHENGGS_VERSION
    HANDLE hFile = CreateFile(file_name.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
        return;
    DWORD dwWriteLen = 0;
    WriteFile(hFile, &bmp.header, sizeof(struct gtBmpHeader), &dwWriteLen, NULL);
    if (bmp.palette)
        WriteFile(hFile, bmp.palette, sizeof(grey8_palette), &dwWriteLen, NULL);
#if (CHENGGS_VERSION == 2 || CHENGGS_VERSION == 5)  // 成光 三、四 期 不要写入 扩展信息 4、5期需要写入
    WriteFile(hFile, &bmp.extension, sizeof(struct gtBmpExtension), &dwWriteLen, NULL);
#endif

    WriteFile(hFile, bmp.data, bmp.header.bitmap_data_size, &dwWriteLen, NULL);
    CloseHandle(hFile);
    return;

#else

    std::ofstream ofs_data;
    ofs_data.open(file_name.c_str(), std::ofstream::out | std::ofstream::binary);
    if (ofs_data.is_open() && ofs_data.good()){
        ofs_data.write((const char*)&bmp.header, sizeof(struct gtBmpHeader));
        if (bmp.palette)
            ofs_data.write((const char*)bmp.palette, sizeof(grey8_palette)/*bmp.header.bitmap_data_offset - sizeof(struct gtBmpHeader) - sizeof(struct gtBmpExtension)*/);
        ofs_data.write((const char*)&bmp.extension, sizeof(struct gtBmpExtension));
        ofs_data.write((const char*)bmp.data, bmp.header.bitmap_data_size);
        ofs_data.close();
    }

#endif

}
/*
void gtBMP::writeToBuffer(void *buf, int size)
{
int offset = 0;
if(ok == false)
return;
if(size < bmp.header.bitmap_data_offset + bmp.header.bitmap_data_size)
return;

memcpy(buf, &bmp.header, sizeof(struct gtBmpHeader));

offset += sizeof(struct gtBmpHeader);
memcpy((char *)buf + offset, (void *)bmp.palette, bmp.header.bitmap_data_offset - sizeof(struct gtBmpHeader));

offset += bmp.header.bitmap_data_offset - sizeof(struct gtBmpHeader);
memcpy((char *)buf + offset, bmp.data, bmp.header.bitmap_data_size);
}

void gtBMP::writeHeader(void *buf)
{
int offset = 0;
if(ok == false)
return;

memcpy(buf, &bmp.header, sizeof(struct gtBmpHeader));
offset += sizeof(struct gtBmpHeader);
memcpy((char *)buf + offset, (void *)bmp.palette, sizeof(grey8_palette));
}
*/
